<template>
  <div 
    :class="[
      ns.b(),
      ns.is('edit', isEdit),
    ]"
  >
    <!-- 编辑模式 可以选择时间  -->
    <div 
      v-if="isEdit"
      :class="[
        ns.e('date-time-picker')
      ]"
    >
      <slot>
        <el-date-picker
          :prefix-icon="prefixIcon"
          :type="type"
          :value="value"
          :format="format"
          :value-format="valueFormat"
          :default-time="bindDefaultTime"
          :placeholder="placeholder"
          :picker-options="pickerOptions"
          :popper-class="pickerPopperClass || formDatePickerClassName"
          v-bind="$attrs"
          @input="onInputHandler" 
          @change="onChangeHandler"
          @focus="handleFocus"
        />
      </slot>
    </div>
    <!-- 查看模式 查看对应时区时间  -->
    <div
      v-else
      :class="[ns.e('view-time')]"
    >
      <span>{{ viewTime }}</span>
    </div>
    <el-popover
      v-if="canUsePopover"
      ref="timezonePopover"
      :popper-class="`${ns.e('date-picker-popper')} ${ns.is('range', isRange)}`"
      :title="t('common.time.transferTime')"
      trigger="click"
      placement="top"
      v-bind="popoverProps"
      @show="showPicker"
    >
      <span
        slot="reference"
      >
        <el-tooltip
          trigger="hover"
          placement="top"
          effect="dark"
          :content="t('common.time.transferTime')"
        >
          <i
            class="iconfont icon-fdn-timeZone" 
            :class="[
              ns.e('clock-icon')
            ]"
          ></i>
        </el-tooltip>
      </span>
      <template>
        <div
          v-if="isEdit"
          :class="[ns.e('row')]"
        >
          <el-date-picker 
            v-model="pickerTime"
            prefix-icon="iconfont icon-fdn-datetime"
            :type="type"
            :format="format"
            :default-time="bindDefaultTime"
            :placeholder="placeholder"
            @change="confirm()"
          ></el-date-picker>
          <span v-if="!isEdit" :class="ns.e('row-icon')"></span>
        </div>
        <div :class="[ns.e('row')]">
          <base-timezone v-model="pickerTimezone" @change="($event) => {changeTimezone($event); confirm();}"></base-timezone>
          <span v-if="!isEdit" :class="ns.e('row-icon')" @click="changeTimezone()"><i class="iconfont icon-dingwei1"></i></span>
        </div>
        <div 
          v-if="isEdit"
          :class="[ns.e('row'), ns.e('operation')]"
        >
          <el-button :class="[ns.e('confirm-button')]" type="primary" @click="confirm">{{ t('common.base.fillingIn') }}</el-button>
        </div>
      </template>
    </el-popover>
  </div>
</template>
<script>
import { defineComponent, ref, unref, computed, watchEffect } from 'vue';
import BaseTimezone from '@src/component/common/BaseTimezone';
import moment from 'moment-timezone'
// utils
import { useNamespace, useTimezoneList, formatDate, isEmpty, isArray, isNumber, isFalsy, getTimestamp, FormatTemplate, isString } from 'pub-bbx-utils';
import { safeNewDate } from '@src/util/time';
// i18n 
import { t } from '@src/locales'
// model
import { useProps, useTimezonePicker } from './picker'

export default defineComponent({
  name: 'BbxTimezoneTimePicker',
  components: {
    BaseTimezone,
  },
  props: useProps,
  emits: ['confirm', 'input'],
  setup(props, { emit }) {
    const ns = useNamespace('timezone-time-picker', 'bbx');

    const timezonePopover = ref()
    function hideTimezonePopover(){
      timezonePopover.value.doClose()
    }

    const pickerTime = ref(props.value);
    const { pickerTimezone, isShowTimezone, useTimezoneCache, changeTimezone } = useTimezonePicker(props.timezone)
    const { zoneIdMap } = useTimezoneList()

    // 是否需要时区转换
    const canUsePopover = computed(() => {
      
      // 如果是时间类型(HH:MM), 不显示
      const dateType = props.field?.setting?.dateType
      const timeTemplates = [FormatTemplate.time, FormatTemplate.fullTime]
      if (timeTemplates.includes(dateType) && isString(props.value) && props.value) {
        return false
      }
      
      // 查看模式是否显示
      const viewShow = !props.isEdit && !isEmpty(props.value) && (!props.format || props.format.indexOf('HH') !== -1)
      // 编辑模式是否显示
      const editShow = props.isEdit && (!props.format || props.format.indexOf('HH') !== -1)
      return props.useTimezonePicker && (viewShow || editShow)
    })
    
    const isDateHour = computed(() => {
      const setting = props.field?.setting || {};
      return Boolean(setting.isDateHour);
    })
    
    const formDatePickerClassName = computed(() => {
      return isDateHour.value ? 'form-date-hour-picker' : '';
    })

    watchEffect(() => {
    // 自动填充时间
      if (pickerTime.value) return;
      pickerTime.value = unref(props.value)
    });

    // 确认事件
    function confirm(e){
      if(!props.isEdit) return
      if(!unref(pickerTime) || !unref(pickerTimezone)) return
      // 有选时区需要转换, 没有不需要转换
      let dateTime
      if(unref(isRange)){
        dateTime = unref(pickerTime).map(item => {
          return formatValue(item)
        })
      }else {
        dateTime = formatValue(unref(pickerTime))
      }
      emit('input', dateTime);
      emit('confirm', dateTime);
      e && hideTimezonePopover()
    }

    // 格式化时间
    function formatValue(dateTime){
      const timestamp = unref(canUsePopover) ? +moment.tz(formatDate(dateTime), unref(pickerTimezone)) : getTimestamp(dateTime)
      // 时间戳
      if(props.valueFormat === 'timestamp') return timestamp
      // 有格式化返回格式化后的时间，没有返回Date
      return props.valueFormat ? formatDate(timestamp, props.valueFormat) : new Date(timestamp)
    }

    // 查看模式下显示的时间
    const viewTime = computed(() => {
      
      // 编辑模式不用计算值
      if(props.isEdit || !unref(props.value)) {
        return ''
      }
      
      const dateType = props.field?.setting?.dateType
      let dateTypeFormat = dateType
      
      if (dateType == 'date') {
        dateTypeFormat = 'yyyy-MM-dd'
      }

      if (dateType == 'dateTime' || dateType == 'datetime') {
        dateTypeFormat = 'yyyy-MM-dd HH:mm:ss'
      }
      
      // 格式
      let format = (props.valueFormat !== 'timestamp' && props.valueFormat) || dateTypeFormat || 'YYYY-MM-DD HH:mm:ss'
      
      format = format.replace('yyyy', 'YYYY').replace('dd', 'DD')
      
      // 未选择时区，直接返回时间
      if(!unref(pickerTimezone)) {
        return formatDate(unref(pickerTime), format)
      }
      
      const time = moment(+props.value || props.value).tz(unref(pickerTimezone)).format(format)
      const timezoneStr = (props.useTimezonePicker && zoneIdMap.get(unref(pickerTimezone))?.introduce) || ''
      return `${time}${unref(isShowTimezone) && timezoneStr ? ` (${timezoneStr})` : ''}`
      
    })

    // 是否区间选择
    const isRange = computed(() => props.type.includes('range') || props.type === 'datetime')

    // 绑定时间
    const bindDefaultTime = computed(() => {
      if(!unref(isRange)) return undefined
      return props.defaultTime ?? (props.type === 'datetime' ? undefined : ['00:00:00', '23:59:59'])
    })

    // 显示选择器
    function showPicker(){
      useTimezoneCache()
    }

    return {
      ns,
      t,
      timezonePopover,
      isRange,
      canUsePopover,
      pickerTime,
      viewTime,
      bindDefaultTime,
      pickerTimezone,
      changeTimezone,
      confirm,
      showPicker,
      isDateHour,
      formDatePickerClassName
    };
  },
  methods: {
    onInputHandler(value) {
      const newValue = this.getNewValue(value)
      this.$emit('input', newValue)
    },
    onChangeHandler(value) {
      const newValue = this.getNewValue(value)
      this.$emit('nativeChange', newValue)
    },
    getNewValue(value) {
      let newValue = value;
      
      const isArrayValue = isArray(newValue);
      const isNotArrayValue = isFalsy(isArrayValue);
      const isNumberValue = isNumber(newValue);
      
      // 如果是年月日小时
      if (this.isDateHour && isNotArrayValue && isNumberValue) {
        // 如果 newValue 不是整点，需要强制转换为整点
        const isHour = newValue % 3600000 === 0;
        if (newValue && isFalsy(isHour)) {
          newValue = safeNewDate(newValue).setMinutes(0, 0, 0);
        }
      }
      
      return newValue;
    },
    handleFocus() {
      
      if (!this.pickerPopperClass) {
        return
      }
      
      this.$nextTick(() => {
        this.handleFocusImpl()
      })
     
    },
    handleFocusImpl() {
      
      const el = document.querySelector(this.pickerPopperClass)
      if (!el) {
        return
      }
      
      
      const spinner = el.querySelector('.el-time-spinner__list')
      if (!spinner) {
        return
      }
      
      const items = spinner.querySelectorAll('.el-time-spinner__item')
      // 如果 item 里面的 class 包含 active，说明已经选中了, 不需要移除这个 item
      items.forEach(item => {
        if (item.classList.contains('active')) {
          return
        }
        spinner.removeChild(item)
      })

    }
  }
});
</script>

<style lang="scss">
@import '../style/index.scss';

.form-date-hour-picker {
  .el-time-spinner {
    .el-time-spinner__wrapper {
      &:nth-of-type(2) {
        .el-scrollbar__wrap {
          overflow: hidden;
        }
        .el-time-spinner__item  {
          display: none;
        }
        .el-time-spinner__item.active {
          display: block;
        }
      }
    }
  }
}
</style>
